/**
 * @file xxx
 * @brief Declaration file of class xxx.
 *
 * This file includes the declaration of class xxx, and
 * the definitions of the macros, struct, enum and so on.
 *
 * @attention used for C++ only.
 */

#include <pthread.h>
#include <stdlib.h>
#include <map>
#include <unistd.h>
#include <stdio.h>

#ifndef __cplusplus
#error ERROR: This file requires C++ compilation (use a .cpp suffix)
#endif

#ifndef SIGNAL_H
#define SIGNAL_H

#include <list>
#include <algorithm>
#include "traits.h"

#define UNUSE(X) (void)(X)

template <typename Class, typename Method>
void impleDoTask(Class* c, Method m, std::tuple<> p)
{
    UNUSE(p);
    (c->*m)();
}

template <typename Class, typename Method, typename T0>
void impleDoTask(Class* c, Method m, std::tuple<T0> p)
{
    (c->*m)(std::get<0>(p));
}
template <typename Class, typename Method, typename T0, typename T1>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4,
    typename T5>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4, T5> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p), std::get<5>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4,
    typename T5, typename T6>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4, T5, T6> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p), std::get<5>(p),
        std::get<6>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4,
    typename T5, typename T6, typename T7>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p), std::get<5>(p),
        std::get<6>(p), std::get<7>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4,
    typename T5, typename T6, typename T7, typename T8>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p), std::get<5>(p),
        std::get<6>(p), std::get<7>(p), std::get<8>(p));
}

template <typename Class, typename Method, typename T0, typename T1, typename T2, typename T3, typename T4,
    typename T5, typename T6, typename T7, typename T8, typename T9>
void impleDoTask(Class* c, Method m, std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> p)
{
    (c->*m)(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p), std::get<4>(p), std::get<5>(p),
        std::get<6>(p), std::get<7>(p), std::get<8>(p), std::get<9>(p));
}

struct TaskBase {
    virtual ~TaskBase() = 0;
    virtual void run() = 0;
};

TaskBase::~TaskBase()
{
}

template <typename Method>
struct NormalTask : public TaskBase {
    typedef typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters Parameters;
    typedef typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value type_value;

    NormalTask(type_value object, Method m, Parameters paras)
        : TaskBase()
        , m_object(object)
        , m_method(m)
        , m_paras(paras)
    {
    }

    virtual ~NormalTask() {}

    void run()
    {
        printf("run:%lu\n", pthread_self());
        fflush(stdout);
        impleDoTask(m_object, m_method, m_paras);
    }

    type_value m_object;
    Method m_method;
    Parameters m_paras;
};

template <bool b>
struct StaticCheck;

template <>
struct StaticCheck<true> {
};

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m)
{
    StaticCheck<ParameterTraits<Method>::size == 0> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras;
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0)
{
    StaticCheck<ParameterTraits<Method>::size == 1> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1)
{
    StaticCheck<ParameterTraits<Method>::size == 2> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2)
{
    StaticCheck<ParameterTraits<Method>::size == 3> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3)
{
    StaticCheck<ParameterTraits<Method>::size == 4> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4)
{
    StaticCheck<ParameterTraits<Method>::size == 5> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4,
    typename ParameterTraits<Method>::P5 p5)
{
    StaticCheck<ParameterTraits<Method>::size == 6> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4, p5);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4,
    typename ParameterTraits<Method>::P5 p5,
    typename ParameterTraits<Method>::P6 p6)
{
    StaticCheck<ParameterTraits<Method>::size == 7> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4, p5, p6);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4,
    typename ParameterTraits<Method>::P5 p5,
    typename ParameterTraits<Method>::P6 p6,
    typename ParameterTraits<Method>::P7 p7)
{
    StaticCheck<ParameterTraits<Method>::size == 8> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4, p5, p6, p7);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4,
    typename ParameterTraits<Method>::P5 p5,
    typename ParameterTraits<Method>::P6 p6,
    typename ParameterTraits<Method>::P7 p7,
    typename ParameterTraits<Method>::P8 p8)
{
    StaticCheck<ParameterTraits<Method>::size == 9> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8);
    return new NormalTask<Method>(object, m, paras);
}

template <typename Method>
TaskBase* NewNormalTask(typename TypeTraits<typename ParameterTraits<Method>::classType_value>::pointerType_value object,
    Method m, typename ParameterTraits<Method>::P0 p0,
    typename ParameterTraits<Method>::P1 p1,
    typename ParameterTraits<Method>::P2 p2,
    typename ParameterTraits<Method>::P3 p3,
    typename ParameterTraits<Method>::P4 p4,
    typename ParameterTraits<Method>::P5 p5,
    typename ParameterTraits<Method>::P6 p6,
    typename ParameterTraits<Method>::P7 p7,
    typename ParameterTraits<Method>::P8 p8,
    typename ParameterTraits<Method>::P9 p9)
{
    StaticCheck<ParameterTraits<Method>::size == 10> a;
    UNUSE(a);
    typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters paras = std::make_tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
    return new NormalTask<Method>(object, m, paras);
}

struct EventLoop {
    EventLoop(pthread_t pid)
        : m_pid(pid)
        , run(true)
    {
    }

    ~EventLoop()
    {
        for (auto ite = m_tasks.begin(); ite != m_tasks.end(); ++ite) {
            delete (*ite);
        }
    }

    void postNormalTask(TaskBase* task)
    {
        m_tasks.push_back(task);
    }

    void test()
    {
        for (auto ite = m_tasks.begin(); ite != m_tasks.end(); ++ite) {
            (*ite)->run();
        }
    }

    pthread_t m_pid;
    bool run;
    std::list<TaskBase*> m_tasks;
    static std::map<pthread_t, EventLoop*> s_eventloops;

    static EventLoop* currentEventLoop()
    {
        EventLoop* re = NULL;
        pthread_t pid = pthread_self();
        std::map<pthread_t, EventLoop*>::iterator ite = s_eventloops.find(pid);
        if (ite != s_eventloops.end()) {
            re = ite->second;
        }
        else {
            re = new EventLoop(pid);
            s_eventloops.insert(std::pair<pthread_t, EventLoop*>(pid, re));
        }
        return re;
    }

    static void exit()
    {
        for (auto ite = s_eventloops.begin(); ite != s_eventloops.end(); ++ite) {
            ite->second->quit();
            delete (ite->second);
        }
        s_eventloops.clear();
    }

    int exec()
    {
        while (run) {
            for (auto ite = m_tasks.begin(); ite != m_tasks.end();) {
                (*ite)->run();
                delete (*ite);
                ite = m_tasks.erase(ite);
            }
            //sleep(10);
        }
        return 1;
    }

    void quit()
    {
        run = false;
    }
};

std::map<pthread_t, EventLoop*> EventLoop::s_eventloops = std::map<pthread_t, EventLoop*>();

struct Box {
    Box()
    {
        m_loop = EventLoop::currentEventLoop();
    }

    EventLoop* m_loop;
};

enum CONNECT_TYPE {
    SYNC,
    AYNC,
    AUTO
};

template <typename Paras>
struct SlotBase {
    SlotBase(CONNECT_TYPE type)
        : m_type(type)
    {
    }

    virtual TaskBase* convertAnormalTask(Paras paras) = 0;

    virtual EventLoop* eventloop() = 0;

    virtual ~SlotBase() = 0;
    virtual void dotask(Paras paras) = 0;
    CONNECT_TYPE m_type;
};

template <typename Paras>
SlotBase<Paras>::~SlotBase()
{
}

template <typename M>
struct Slot : public SlotBase<typename ParameterTupleTraits<ParameterTraits<M> >::Parameters> {

    typedef typename TypeTraits<typename ParameterTraits<M>::classType_value>::pointerType_value type_value;
    typedef typename ParameterTupleTraits<ParameterTraits<M> >::Parameters Parameters;
    Slot(type_value sloter, M method, CONNECT_TYPE type)
        : SlotBase<Parameters>(type)
        , m_object(sloter)
        , m_method(method)
    {
    }

    void dotask(Parameters paras)
    {
        impleDoTask(m_object, m_method, paras);
    }

    TaskBase* convertAnormalTask(Parameters paras)
    {
        return new NormalTask<M>(m_object, m_method, paras);
    }

    EventLoop* eventloop()
    {
        return m_object->m_loop;
    }

    type_value m_object;
    M m_method;
};

template <typename Method>
struct Signal {
    ~Signal()
    {
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            delete (*ite);
        }
        sloters.clear();
    }

    template <typename M>
    bool connect(typename Slot<M>::type_value object, M method, CONNECT_TYPE type = AUTO)
    {
        typename listValue_type::const_iterator ite = std::find_if(sloters.begin(), sloters.end(), FindHelper<M>(object, method));
        if (ite != sloters.end()) {
            return false;
        }
        sloters.push_back(new Slot<M>(object, method, type));
        return true;
    }

    template <typename M>
    bool disconnect(typename Slot<M>::type_value object, M method)
    {
        typename listValue_type::iterator ite = std::find_if(sloters.begin(), sloters.end(), FindHelper<M>(object, method));
        if (ite != sloters.end()) {
            delete (*ite);
            sloters.erase(ite);
            return true;
        }
        return false;
    }

    void eemit()
    {
        printf("eemit:%lu\n", pthread_self());
        fflush(stdout);
        std::tuple<> para;
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0>
    void eemit(T0 t)
    {
        printf("eemit:%lu\n", pthread_self());
        fflush(stdout);
        std::tuple<T0> para = std::make_tuple(t);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
            //(*ite)->dotask(para);
        }
    }

    template <typename T0, typename T1>
    void eemit(T0 t, T1 t1)
    {
        printf("eemit:%lu\n", pthread_self());
        fflush(stdout);
        std::tuple<T0, T1> para = std::make_tuple(t, t1);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2>
    void eemit(T0 t, T1 t1, T2 t2)
    {
        std::tuple<T0, T1, T2> para = std::make_tuple(t, t1, t2);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3)
    {
        std::tuple<T0, T1, T2, T3> para = std::make_tuple(t, t1, t2, t3);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4)
    {
        std::tuple<T0, T1, T2, T3, T4> para = std::make_tuple(t, t1, t2, t3, t4);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
    {
        std::tuple<T0, T1, T2, T3, T4, T5> para = std::make_tuple(t, t1, t2, t3, t4, t5);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
        typename T6>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
    {
        std::tuple<T0, T1, T2, T3, T4, T5, T6> para = std::make_tuple(t, t1, t2, t3, t4, t5, t6);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
        typename T6, typename T7>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
    {
        std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> para = std::make_tuple(t, t1, t2, t3, t4, t5, t6, t7);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
        typename T6, typename T7, typename T8>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
    {
        std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> para = std::make_tuple(t, t1, t2, t3, t4, t5, t6, t7, t8);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
        typename T6, typename T7, typename T8, typename T9>
    void eemit(T0 t, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
    {
        std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> para = std::make_tuple(t, t1, t2, t3, t4, t5, t6, t7, t8, t9);
        for (typename listValue_type::iterator ite = sloters.begin(); ite != sloters.end(); ++ite) {
            CONNECT_TYPE type = (*ite)->m_type;
            switch (type) {
            case SYNC: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            case AYNC: {
                (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
            };
                break;
            case AUTO: {
                if (EventLoop::currentEventLoop() == ((*ite)->eventloop())) {
                    (*ite)->dotask(para);
                }
                else {
                    (*ite)->eventloop()->postNormalTask((*ite)->convertAnormalTask(para));
                }
            };
                break;
            default:
                break;
            }
        }
    }

    //使用Method来实例化list，是为了在connect的时候，防止Method和M不一致，也就是参数不一致。
    typedef std::list<SlotBase<typename ParameterTupleTraits<ParameterTraits<Method> >::Parameters>*> listValue_type;
    listValue_type sloters;

    template <typename T>
    struct FindHelper {
        FindHelper(typename Slot<T>::type_value object, T method)
            : m_object(object)
            , m_method(method)
        {
        }

        bool operator()(const typename listValue_type::value_type& val) const
        {
            const Slot<T>* p = static_cast<Slot<T>*>(val);
            return (p->m_object == m_object) && (p->m_method == m_method);
        }

        bool operator()(typename listValue_type::value_type& val)
        {
            const Slot<T>* p = static_cast<Slot<T>*>(val);
            return (p->m_object == m_object) && (p->m_method == m_method);
        }

        typename Slot<T>::type_value m_object;
        T m_method;

    };

};

#endif // SIGNAL_H
